﻿__author__ = 'YT'

from .component import map
from . import AStarSearch, tool

class EnemyInfo():
    def __init__(self, enemy):
        # 构造方法用于初始化 EnemyInfo 对象。
        # 参数：
        # - enemy: 表示敌人的类型或名称。
        self.enemy = enemy  # 将提供的敌人参数赋值给 'enemy' 属性。

        # 敌人特征的默认值。
        self.range_num = 100  # 敌人的默认攻击范围。
        self.kill_time = 1000  # 敌人击毙所需的默认时间。
        self.remote = False  # 表示敌人是否远程攻击的默认值。

# 开发的AI方法(基于运筹学)         
def getAction(entity, map, enemy_group, name = "myAI"):
    def getDestination(entity, map, enemy):
        # 获取敌人可能的攻击目标位置列表。
        dir_list = tool.getAttackPositions(enemy.map_x, enemy.map_y)
        
        # 初始化最佳位置和最小距离。
        best_pos = None
        min_dis = 0

        # 遍历可能的攻击目标位置。
        for offset_x, offset_y in dir_list:
            x, y = enemy.map_x + offset_x, enemy.map_y + offset_y

            # 检查目标位置是否有效且可移动。
            if map.isValid(x, y) and map.isMovable(x, y):
                # 使用A*搜索算法计算实体到目标位置的距离。
                distance = AStarSearch.getAStarDistance(map, (entity.map_x, entity.map_y), (x, y))

                # 如果无法到达目标位置，则继续下一个位置。
                if distance is None:
                    continue

                # 更新最佳位置和最小距离。
                if best_pos is None:
                    best_pos = (x, y)
                    min_dis = distance
                elif distance < min_dis:
                    best_pos = (x, y)
                    min_dis = distance

        # 返回最佳位置作为攻击目标。
        return best_pos

    # [内部方法，用于获得EnemyInfo]
    def getEnemyInfo(info_list, entity, enemy, destination, name = "myAI"):
        # 创建一个EnemyInfo对象，用于存储敌人的信息。
        enemyinfo = EnemyInfo(enemy)
        # 使用A*搜索算法找到实体到目标位置的路径。
        location = AStarSearch.AStarSearch(map, (entity.map_x, entity.map_y), destination)
        # 获取路径的第一步和总距离。
        _, _, distance = AStarSearch.getFirstStepAndDistance(location)
        # 打印调试信息，显示实体位置、目标位置、路径位置以及路径距离。
        print(name + ":")
        print('entity(%d, %d), dest(%d, %d) location(%d, %d) distance:%d' % 
            (entity.map_x, entity.map_y, destination[0], destination[1], location.x, location.y, distance))
    
        # 如果距离为0，表示实体已经在目标位置上，将敌人的攻击范围设为0。
        if distance == 0:
            enemyinfo.range_num = 0
        else:
            # 计算敌人的攻击范围，考虑实体的攻击范围。
            enemyinfo.range_num = (distance - 1) // entity.attr.range
    
        # 将路径信息、距离等添加到EnemyInfo对象中。
        enemyinfo.location = location
        enemyinfo.distance = distance

        # 计算实体对敌人的伤害，以及击毙敌人所需的时间。
        hurt = entity.attr.getHurt(enemy.attr)
        enemyinfo.kill_time = (enemy.health-1) // hurt
        #print('hurt(%d), kill_time(%d)' % (hurt, enemyinfo.kill_time)) 

        # 将敌人是否远程攻击的信息添加到EnemyInfo对象中。
        enemyinfo.remote = enemy.attr.remote
        # 将EnemyInfo对象添加到信息列表中。
        info_list.append(enemyinfo)

    info_list = []
    best_info = None

    # 遍历敌人组中的每个敌人。
    for enemy in enemy_group:
        # 如果实体与敌人相邻，设置目标位置为当前实体位置。
        if tool.isNextToEntity(entity, enemy):
            print('entity(%d,%d) next to enemy(%d, %d)' % (entity.map_x, entity.map_y, enemy.map_x, enemy.map_y))
            destination = (entity.map_x, entity.map_y)
        else:
            # 否则，获取实体到敌人的可能攻击目标位置。
            destination = getDestination(entity, map, enemy)
    
        # 如果目标位置存在，则获取有关敌人的信息并存储在info_list中。
        if destination is not None:
            getEnemyInfo(info_list, entity, enemy, destination, name)

    # 在info_list中选择最佳的敌人信息。
    # 遍历info_list列表
    for info in info_list:
        # 如果best_info为空，则将info赋值给best_info
        if best_info == None:
            best_info = info
        # 否则，比较info和best_info的range_num
        else:
            # 如果info的range_num小于best_info的range_num
            if info.range_num < best_info.range_num:
                # 将info赋值给best_info
                best_info = info
            # 如果info的range_num等于best_info的range_num
            elif info.range_num == best_info.range_num:
                # 如果info的range_num为0
                if info.range_num == 0:
                    # 如果info的kill_time小于best_info的kill_time
                    if info.kill_time < best_info.kill_time:
                        # 将info赋值给best_info
                        best_info = info
                    # 如果info的kill_time等于best_info的kill_time
                    elif info.kill_time == best_info.kill_time:
                        # 如果info的remote为True，best_info的remote为False
                        if info.remote == True and best_info.remote == False:
                            # 将info赋值给best_info
                            best_info = info
                        # 如果info的distance小于best_info的distance
                        elif info.distance < best_info.distance:
                            # 将info赋值给best_info
                            best_info = info
                # 如果info的range_num不为0
                else:
                    # 如果info的distance小于best_info的distance
                    if info.distance < best_info.distance:
                        # 将info赋值给best_info
                        best_info = info

    # 根据最佳的敌人信息确定实体的下一步行动。
    if best_info.range_num == 0:
        # 如果最佳敌人的攻击范围为0，返回实体当前位置作为目标。
        return (best_info.location.x, best_info.location.y, best_info.enemy)
    elif best_info.range_num == 1:
        # 如果最佳敌人的攻击范围为1，返回实体在自身攻击范围内的位置作为目标。
        range = entity.attr.range
        x, y = AStarSearch.getPosInRange(best_info.location, range)
        return (x, y, None)
    else:
        # 如果最佳敌人的攻击范围大于1，返回实体在最佳敌人攻击范围外的位置作为目标。
        range = best_info.distance - entity.attr.range
        x, y = AStarSearch.getPosInRange(best_info.location, range)
        return (x, y, None)
